<template>
	<view id="video-container" :options="options" :change:options="domVideo.changeOptions" :method="method"
		:change:method="domVideo.changeMethod" :playInterval="playInterval" :change:playInterval="domVideo.changePlayInterval">
	</view>
</template>

<script>
	/**
	 * dom-video web原生video组件的uniapp版本，支持H5、APP。
	 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
	 * @description 这是一个用于展示视频的组件，支持H5、APP。
	 * @property {String} src 视频的URL地址 仅支持网络地址和从相册选择的视频。
	 * @property {Boolean} autoplay 一个布尔属性；声明该属性后，视频会尽快自动开始播放，不会停下来等待数据全部加载完成。
	 * @property {Boolean} controls 如果存在该属性，浏览器会在视频底部提供一个控制面板，允许用户控制视频的播放，包括音量、拖动进度、暂停或恢复播放。
	 * @property {Boolean} loop 如果存在该属性，视频将在播放完毕后再次开始播放。
	 * @property {Boolean} muted 如果存在该属性，视频的音频部分将被静音。
	 * @property {Boolean} playsinline 如果存在该属性，视频将在其元素内播放，不会占用整个浏览器窗口。
	 * @property {String} controlslist 当浏览器显示视频底部的播放控制面板（例如，指定了 controls 属性）时，controlslist 属性会帮助浏览器选择在控制面板上显示哪些 video 元素控件。允许的值有 nodownload、nofullscreen 和 noremoteplayback。
	 * @value nodownload
	 * @value nofullscreen
	 * @value noremoteplayback
	 * @property {String} preload 该枚举属性旨在提示浏览器，作者认为在播放视频之前，加载哪些内容会达到最佳的用户体验。可能是下列值之一：
	 * @value none: 表示不应该预加载视频。
	 * @value metadata: 表示仅预先获取视频的元数据（例如长度）。
	 * @value auto: 表示可以下载整个视频文件，即使用户不希望使用它。
	 * @value 空字符串: 与 auto 值一致。
	 * @event {Function} click 点击组件时触发
	 * @event {Function} close 点击关闭按钮时触发
	 */
	export default {
		computed: {
			options() {
				return {
					controls: true,
					autoplay: true,
					loop: true,
					muted: true,
					playsInline: true,
					preload: 'metadata',
					crossOrigin: 'anonymous',
					...this.$attrs
				}
			},
		},
		data() {
			return {
				// attr
				method: {
					name: '',
					data: '',
					time: 0 // 解决当重复调用相同方法时，无法触发renderjs的问题。
				},
				playInterval: {
					start: 0, // 开始播放的时间点，单位为秒。
					end: 0, // 结束播放的时间点，单位为秒。
				}
			}
		},
		methods: {
			setPlayInterval(data){
				this.playInterval = data
			},
			/**
			 * @param {Object} method { name:'方法名', data:'参数' }
			 */
			callMethod(method, data = '') {
				this.method = {
					name: method,
					data: data,
					time: new Date().getTime()
				}
			},
			// 将video的事件传递给父组件
			videoEvent(event) {
				// console.log('向父组件传递事件 =>', data)
				this.$emit(event.eventName, event.value)
			}
		},
		onReady() {

		},
		onLoad() {},
	}
</script>

<script module="domVideo" lang="renderjs">
	export default {
		data() {
			return {
				video: null,
				options: {},
				hasEventListener: []
			}
		},
		methods: {
			// 设置在时间段内播放视频。start: 开始播放的时间点，单位为秒。end: 结束播放的时间点，单位为秒。
			changePlayInterval(val) {
				if (!this.video) return
				// 设置视频的开始时间
				this.video.currentTime = val.start;
				// 监听视频时间更新事件
				this.video.addEventListener('timeupdate', ()=> {
					if (this.video.currentTime >= val.end) {
						this.video.pause(); // 在结束时间暂停视频
						this.video.currentTime = val.start; // 可选：重置到开始时间
						if(this.options.loop){
							this.video.play(); // 循环播放，如果loop为true，则重新播放视频。
						}
					}
				});
			},
			changeMethod(method) {
				if (!method.name) return;
				if (method.data) {
					this.video[method.name](method.data)
				} else {
					this.video[method.name]()
				}
			},
			setVideoAttr(attrs) {
				for (let key in attrs) {
					if (key == 'events') {
						// 监听视频事件
						for (let event of attrs[key]) {
							if (this.hasEventListener.includes(event)) continue;
							this.video.addEventListener(event, (e) => {
								// 这个e只能打印出{"isTrusted":true} 毛用没有
								this.$ownerInstance.callMethod('videoEvent', {
									eventName: event,
									value: {
										// 这里可以获取到视频的时长，当前播放时间，当前播放状态等信息。
										duration: this.video.duration, // 视频时长，单位为秒。
										currentTime: this.video.currentTime, // 当前播放时间，单位为秒。
										paused: this.video.paused, // 当前播放状态，true表示暂停，false表示播放。
										// 这里可以添加更多视频信息，根据需要获取。
										// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/volumechange_event
									}
								})
							})
							this.hasEventListener.push(event)
						}
					} else {
						this.video[key] = attrs[key];
					}
				}
			},
			changeOptions(data) {
				if (!this.video) {
					this.options = data
				} else {
					for (let key in data) {
						this.setVideoAttr(data)
					}
				}
			},
			createVideo() {
				this.video = document.createElement('video')
				this.setVideoAttr(this.options)
				this.video.style.width = '100%'
				this.video.style.height = '100%'
				// 原生不支持的方法自己加 跳转到指定的时间点。time: 单位为秒。
				this.video.seek = function(time = 0) {
					this.currentTime = time;
				}
				document.getElementById('video-container').appendChild(this.video)
			}
		},
		mounted() {
			this.createVideo()
		},
		unMounted() {
			this.video = null
		},
	}
</script>

<style>

</style>